package pers.bc.utils.yonyou;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 

import nc.bcmanage.bs.IBusiCenterManageService;
import nc.bcmanage.vo.BusiCenterVO;
import nc.bs.framework.common.NCLocator;
import nc.bs.framework.redis.Domains;
import nc.bs.framework.redis.collections.adapter.MapAdapter;
import nc.bs.logging.Logger;
import nc.login.bs.INCUserQueryService;
import nc.vo.sm.UserVO;
import ncc.sso.bs.NCCSSOConfigVO;
import ncc.sso.bs.NCCSSORegInfo;
import nccloud.baseapp.redis.rediskey.RedisKeyConstant;
import pers.bc.utils.Bean.ObjectUtil;
import pers.bc.utils.Bean.ReflectionUtil;

public class NCCSSORegisterCenter
{
    private static NCCSSORegisterCenter instance = null;
    private Map<String, NCCSSORegInfo> regInfoMap;
    private List<BusiCenterVO> bcList;
    
    public static NCCSSORegisterCenter getInstance()
    {
        if (instance == null)
        {
            synchronized (NCCSSORegisterCenter.class)
            {
                if (instance == null)
                {
                    instance = new NCCSSORegisterCenter();
                }
            }
        }
        
        return instance;
    }
    
    private NCCSSORegisterCenter()
    {
        this.regInfoMap =
            Collections.synchronizedMap(new MapAdapter(Domains.RIA, RedisKeyConstant.baseapp_NCCSSORegisterCenter_regInfoMap));
        this.bcList = null;
        Runnable run = new NCCSSORegisterCenterRunnable();
        (new Thread(run)).start();
    }
    
    public static NCCSSOConfigVO getSSOConfigVO()
    {
        return ncc.sso.bs.NCCSSOConfigParser.getInstances().getSSOConfigVO();
    }
    
    public void registerNCCSSORegInfo(NCCSSORegInfo regInfo)
    {
        String access_token = regInfo.getAccess_token();
        Map<BusiCenterVO, UserVO> availableBCs = this.getAvailableBusiCenters(regInfo);
        regInfo.putAttachProp("availableBCs", availableBCs);
        int timeOut = 120000;
        long expiredTime = System.currentTimeMillis() + (long) timeOut;
        regInfo.putAttachProp("expiredTime", expiredTime);
        this.regInfoMap.put(access_token, regInfo);
    }
    
    public void registerNCCSSORegInfo(NCCSSORegInfo regInfo, int regTimeOut)
    {
        String access_token = regInfo.getAccess_token();
        Map<BusiCenterVO, UserVO> availableBCs = this.getAvailableBusiCenters(regInfo);
        regInfo.putAttachProp("availableBCs", availableBCs);
        long expiredTime = System.currentTimeMillis() + (long) regTimeOut;
        regInfo.putAttachProp("expiredTime", expiredTime);
        this.regInfoMap.put(access_token, regInfo);
    }
    
    public NCCSSORegInfo fetchSSORegInfo(String access_token)
    {
        // (NCCSSORegInfo)this.regInfoMap.remove(access_token);
        // 20250301 外貿項目 获取SSO注册信息問題
        Object obj = this.regInfoMap.get(access_token);
        
        if (obj instanceof Map)
        {
            // Map转换成对象
            NCCSSORegInfo regInfo = ReflectionUtil.newInstance(NCCSSORegInfo.class);
            Map temp = (Map) this.regInfoMap.get(access_token);
            for (Object key : temp.keySet())
            {
                Object value = temp.get(key);
                try
                {
                    ObjectUtil.set(regInfo, key, value);
                }
                catch (Exception e)
                {
                }
            }
            this.regInfoMap.remove(access_token);
            return regInfo;
        }
        else
        	obj = ((NCCSSORegInfo) (this.regInfoMap.get(access_token)));
        this.regInfoMap.remove(access_token);
        
        return  (NCCSSORegInfo) obj;
    }
    
    private Map<BusiCenterVO, UserVO> getAvailableBusiCenters(NCCSSORegInfo regInfo)
    {
        String regBSCode = regInfo.getBusiCenterCode();
        String userCode = regInfo.getUsercode();
        Map<BusiCenterVO, UserVO> map = new HashMap();
        INCUserQueryService service = (INCUserQueryService) NCLocator.getInstance().lookup(INCUserQueryService.class);
        int count = this.getBusiCenterList().size();
        
        for (int i = 0; i < count; ++i)
        {
            BusiCenterVO bcvo = (BusiCenterVO) this.getBusiCenterList().get(i);
            String bsCode = bcvo.getCode();
            if (regBSCode == null || regBSCode.equals(bsCode))
            {
                String dsName = bcvo.getDataSourceName();
                
                try
                {
                    UserVO user = service.findUserVO(dsName, userCode);
                    if (user != null)
                    {
                        map.put(bcvo, user);
                    }
                }
                catch (Exception e)
                {
                    Logger.error(e.getMessage(), e);
                }
            }
        }
        
        return map;
    }
    
    private List<BusiCenterVO> getBusiCenterList()
    {
        if (this.bcList == null)
        {
            IBusiCenterManageService service = (IBusiCenterManageService) NCLocator.getInstance().lookup(IBusiCenterManageService.class);
            
            try
            {
                BusiCenterVO[] bcVOs = service.getBusiCenterVOs();
                this.bcList = new ArrayList(Arrays.asList(bcVOs));
            }
            catch (Exception e)
            {
                Logger.error(e.getMessage(), e);
            }
        }
        
        return this.bcList;
    }
    
    private class NCCSSORegisterCenterRunnable implements Runnable
    {
        private NCCSSORegisterCenterRunnable()
        {
        }
        
        public void run()
        {
            while (true)
            {
                try
                {
                    Thread.sleep(1000L);
                    long currTime = System.currentTimeMillis();
                    synchronized (NCCSSORegisterCenter.this.regInfoMap)
                    {
                        for (String ssoKey : NCCSSORegisterCenter.this.regInfoMap.keySet())
                        {
                            NCCSSORegInfo regInfo = (NCCSSORegInfo) NCCSSORegisterCenter.this.regInfoMap.get(ssoKey);
                            if (regInfo != null)
                            {
                                long expiredTime = (Long) regInfo.getAttachedProp("expiredTime");
                                if (currTime > expiredTime)
                                {
                                    NCCSSORegisterCenter.this.regInfoMap.remove(ssoKey);
                                    Logger.debug("SSO register info has timeout: ssokey='" + ssoKey + "'。");
                                }
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    Logger.error(e.getMessage(), e);
                }
            }
        }
    }
}
